using TestCases.CompareAssert.Core.Comparers.Generics;
using TestCases.CompareAssert.Core.Interfaces;
using TestCases.CompareAssert.Core.Selectors;

namespace TestCases.CompareAssert.Core.Comparers.Collections
{
    public abstract class CompatibleInterfacesComparer<TInterface>: GenericComparer
    {
        protected CompatibleInterfacesComparer(string interfaceName) : base(new CompatibleInterfacesSelector(interfaceName))
        {
        }

        public abstract IResultBuilder CompareVia(TInterface leftObj, TInterface rightObj, ICompareContext context);

        public override IResultBuilder Compare(ICompareContext context)
        {
            var result = CompareViaInterfaces(context);
            if (result != null)
            {
                return result;
            }

            if (!(context.LValue is TInterface))
            {
                return this.IsNotApplicable(context).Left.IsNot<TInterface>();
            }

            if (!(context.RValue is TInterface))
            {
                return this.IsNotApplicable(context).Right.IsNot<TInterface>();
            }

            return CompareVia((TInterface) context.LValue, (TInterface) context.RValue, context);
        }
    }
}